/*****************************************************************************
 * hal_opl1x_spi.c
 *
 * Copyright (C) 2019 Jeasonvor <1101627719@qq.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 ****************************************************************************/

/*****************************************************************************
 * Included Files
 ****************************************************************************/

#include "plum_api.h"
#include "hal/source/hal_opl1x/hal_opl1x.h"

/*****************************************************************************
 * Trace Definitions
 ****************************************************************************/
#define LOG_RUN_LEVEL LOG_LEVEL_DEBUG
#define LOG_MODULE    "hal.spi"
#include "thirdparty/log/log.h"
/*****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

/*****************************************************************************
 * Private Types
 ****************************************************************************/

typedef struct {
    plum_u32         idx;
    struct list_head list;
} hal_spi_hdl_t;
/*****************************************************************************
 * Private Function Prototypes
 ****************************************************************************/

/*****************************************************************************
 * Private Data
 ****************************************************************************/
PLUM_PRIVATE hal_spi_hdl_t spi_head;
/*****************************************************************************
 * Public Data
 ****************************************************************************/

/*****************************************************************************
 * Private Functions
 ****************************************************************************/

PLUM_PRIVATE
E_SpiIdx_t hal_opl1x_spi_idx(plum_u32 id)
{
    E_SpiIdx_t idx = SPI_IDX_MAX;

    switch (PLUM_HAL_SPI_IDX(id)) {
        case 0:
            idx = SPI_IDX_0;
            break;
        case 1:
            idx = SPI_IDX_1;
            break;
        case 2:
            idx = SPI_IDX_2;
            break;
        default:
            break;
    }

    return (idx);
}

PLUM_PRIVATE
plum_u8 hal_opl1x_spi_gpio_pin(plum_u32 id)
{
    plum_u8 idx = BLANK_PIN;

    switch (PLUM_HAL_GPIO_PIN(id)) {
#if defined(OPL1000_IO0_PIN)
        case 0:
            idx = OPL1000_IO0_PIN;
            break;
#endif
#if defined(OPL1000_IO1_PIN)
        case 1:
            idx = OPL1000_IO1_PIN;
            break;
#endif
#if defined(OPL1000_IO2_PIN)
        case 2:
            idx = OPL1000_IO2_PIN;
            break;
#endif
#if defined(OPL1000_IO3_PIN)
        case 3:
            idx = OPL1000_IO3_PIN;
            break;
#endif
#if defined(OPL1000_IO4_PIN)
        case 4:
            idx = OPL1000_IO4_PIN;
            break;
#endif
#if defined(OPL1000_IO5_PIN)
        case 5:
            idx = OPL1000_IO5_PIN;
            break;
#endif
#if defined(OPL1000_IO6_PIN)
        case 6:
            idx = OPL1000_IO6_PIN;
            break;
#endif
#if defined(OPL1000_IO7_PIN)
        case 7:
            idx = OPL1000_IO7_PIN;
            break;
#endif
#if defined(OPL1000_IO8_PIN)
        case 8:
            idx = OPL1000_IO8_PIN;
            break;
#endif
#if defined(OPL1000_IO9_PIN)
        case 9:
            idx = OPL1000_IO9_PIN;
            break;
#endif
#if defined(OPL1000_IO10_PIN)
        case 10:
            idx = OPL1000_IO10_PIN;
            break;
#endif
#if defined(OPL1000_IO11_PIN)
        case 11:
            idx = OPL1000_IO11_PIN;
            break;
#endif
#if defined(OPL1000_IO12_PIN)
        case 12:
            idx = OPL1000_IO12_PIN;
            break;
#endif
#if defined(OPL1000_IO13_PIN)
        case 13:
            idx = OPL1000_IO13_PIN;
            break;
#endif
#if defined(OPL1000_IO14_PIN)
        case 14:
            idx = OPL1000_IO14_PIN;
            break;
#endif
#if defined(OPL1000_IO15_PIN)
        case 15:
            idx = OPL1000_IO15_PIN;
            break;
#endif
#if defined(OPL1000_IO16_PIN)
        case 16:
            idx = OPL1000_IO16_PIN;
            break;
#endif
#if defined(OPL1000_IO17_PIN)
        case 17:
            idx = OPL1000_IO17_PIN;
            break;
#endif
#if defined(OPL1000_IO18_PIN)
        case 18:
            idx = OPL1000_IO18_PIN;
            break;
#endif
#if defined(OPL1000_IO19_PIN)
        case 19:
            idx = OPL1000_IO19_PIN;
            break;
#endif
#if defined(OPL1000_IO20_PIN)
        case 20:
            idx = OPL1000_IO20_PIN;
            break;
#endif
#if defined(OPL1000_IO21_PIN)
        case 21:
            idx = OPL1000_IO21_PIN;
            break;
#endif
#if defined(OPL1000_IO22_PIN)
        case 22:
            idx = OPL1000_IO22_PIN;
            break;
#endif
#if defined(OPL1000_IO23_PIN)
        case 23:
            idx = OPL1000_IO23_PIN;
            break;
#endif
        default:
            break;
    }

    return (idx);
}

PLUM_PRIVATE
E_SpiDataFrameSize_t hal_opl1x_spi_data_size(plum_u8 size)
{
    E_SpiDataFrameSize_t fmtsz = SPI_DFS_08_bit;

    switch (size) {
        case 4:
            fmtsz = SPI_DFS_04_bit;
            break;
        case 5:
            fmtsz = SPI_DFS_05_bit;
            break;
        case 6:
            fmtsz = SPI_DFS_06_bit;
            break;
        case 7:
            fmtsz = SPI_DFS_07_bit;
            break;
        case 8:
            fmtsz = SPI_DFS_08_bit;
            break;
        case 9:
            fmtsz = SPI_DFS_09_bit;
            break;
        case 10:
            fmtsz = SPI_DFS_10_bit;
            break;
        case 11:
            fmtsz = SPI_DFS_11_bit;
            break;
        case 12:
            fmtsz = SPI_DFS_12_bit;
            break;
        case 13:
            fmtsz = SPI_DFS_13_bit;
            break;
        case 14:
            fmtsz = SPI_DFS_14_bit;
            break;
        case 15:
            fmtsz = SPI_DFS_15_bit;
            break;
        case 16:
            fmtsz = SPI_DFS_16_bit;
            break;
        default:
            break;
    }

    return (fmtsz);
}
PLUM_PRIVATE
plum_s32 hal_opl1x_spi_soft_init(plum_u32 id, plum_hal_spi_cof_t *config)
{
    plum_s32 rc = PLUM_ECODE_OK;

    do {

    } while (0);

    return (rc);
}

PLUM_PRIVATE
plum_s32 hal_opl1x_spi_hard_init(plum_u32 id, plum_hal_spi_cof_t *cof)
{
    plum_s32 rc = PLUM_ECODE_OK;

    do {
        T_OPL1000_Spi spi = {SPI_IDX_MAX};

        spi.index    = hal_opl1x_spi_idx(id);
        spi.clk      = hal_opl1x_spi_idx(cof->pin.clk_pin);
        spi.miso     = hal_opl1x_spi_idx(cof->pin.miso_pin);
        spi.mosi     = hal_opl1x_spi_idx(cof->pin.mosi_pin);
        spi.io2      = BLANK_PIN;
        spi.io3      = BLANK_PIN;
        spi.baudrate = cof->freq;
        spi.polar    = SPI_CLK_PLOAR_HIGH_ACT;
        spi.phase    = SPI_CLK_PHASE_START;
        spi.format   = SPI_FMT_MOTOROLA;
        spi.size     = hal_opl1x_spi_data_size(cof->word_width);
        spi.qMode    = QMODE_ENABLE;

        rc = Hal_Pinmux_Spi_Init(&spi);
        if (rc) {
            LOG_E("Hal_Pinmux_Spi_Init err,rc: %d", rc);
            rc = PLUM_ECODE_EIO;
            break;
        }

        rc = Hal_Spi_Init(spi.index, spi.baudrate, spi.polar, spi.phase,
                          spi.format, spi.size, spi.qMode);
        if (rc) {
            LOG_E("Hal_Spi_Init err,rc: %d", rc);
            rc = PLUM_ECODE_EIO;
            break;
        }
    } while (0);

    return (rc);
}
/*****************************************************************************
 * Public Functions
 ****************************************************************************/

PLUM_PUBLIC
plum_s32 plum_hal_spi_init(plum_u32 id, plum_hal_spi_cof_t *config)
{
    plum_s32 rc = PLUM_ECODE_OK;

    do {
        if (!PLUM_HAL_ID_IS_SPI(id)) {
            LOG_E("it is not a spi id: 0x%08X", id);
            rc = PLUM_ECODE_INVALID;
            break;
        }

        if (!spi_head.list.next) {
            INIT_LIST_HEAD(&spi_head.list);
        }

        if (PLUM_HAL_SPI_IDX(id) <= 100) {
            rc = hal_opl1x_spi_hard_init(id, config);
        }
        else {
            rc = hal_opl1x_spi_soft_init(id, config);
        }
        if (rc) {
            LOG_E("hal_spi_init err,rc: %d", rc);
            break;
        }

    } while (0);

    return (rc);
}

/****************************************************************************/
/*                                                                          */
/*  End of file.                                                            */
/*                                                                          */
/****************************************************************************/
